package cc.cix.gt.common.util;

import cc.cix.gt.common.constant.RedisConstant;
import cc.cix.gt.common.exception.SystemException;
import cc.cix.gt.common.properties.ValidateCodeProperties;
import cc.cix.gt.org.dto.response.ImageCodeResp;
import cn.hutool.core.img.ImgUtil;
import com.wf.captcha.GifCaptcha;
import com.wf.captcha.SpecCaptcha;
import com.wf.captcha.base.Captcha;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.servlet.http.HttpServletRequest;
import java.util.concurrent.TimeUnit;

/**
 * @author cix
 */
@Component
public record ValidateCodeUtil(ValidateCodeProperties validateCodeProperties,
                               StringRedisTemplate stringRedisTemplate) {

    private static ValidateCodeProperties validateCodePropertiesInstance;
    private static StringRedisTemplate stringRedisTemplateInstance;

    @PostConstruct
    private void init() {
        validateCodePropertiesInstance = validateCodeProperties;
        stringRedisTemplateInstance = stringRedisTemplate;
    }

    public static ImageCodeResp create(HttpServletRequest request) {
        Captcha captcha = createCaptcha(validateCodePropertiesInstance);

        String key = String.format(RedisConstant.IMAGE_CODE, request.getSession().getId());
        String value = StringUtils.lowerCase(captcha.text());
        stringRedisTemplateInstance.opsForValue().set(key, value,
                validateCodePropertiesInstance.getTime().getSeconds(), TimeUnit.SECONDS);

        return ImageCodeResp.builder()
                .key(key)
                .img(captcha.toBase64("data:image/png;base64,"))
                .build();
    }

    public static void check(String key, String value) throws SystemException {
        String code = stringRedisTemplateInstance.opsForValue().get(key);

        if (!StringUtils.equalsIgnoreCase(value, code)) {
            throw new SystemException("验证码不正确");
        }

        // 校验成功删除验证码
        stringRedisTemplateInstance.delete(key);
    }

    private static Captcha createCaptcha(ValidateCodeProperties code) {
        Captcha captcha;
        if (StringUtils.equalsIgnoreCase(code.getType(), ImgUtil.IMAGE_TYPE_GIF)) {
            captcha = new GifCaptcha(code.getWidth(), code.getHeight(), code.getLength());
        } else {
            captcha = new SpecCaptcha(code.getWidth(), code.getHeight(), code.getLength());
        }
        captcha.setCharType(code.getCharType());
        return captcha;
    }

}
